<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/22 0022
 * Time: 上午 10:43
 */
namespace app\common\command;

use app\admin\model\Groupdetail;
use app\admin\model\OrderAfterSale;
use app\admin\model\Orderitem;
use app\api\service\Detailed;
use app\common\BaseHelper;
use app\common\DictConstant;
use app\common\service\Utils;
use app\lib\exception\ParameterException;
use app\lib\redis\Redis;
use think\Db;
use think\Exception;
use think\Loader;

Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');

/**
 * 团购自动退款
 * Class Group
 * @package app\common\command
 */
class Group{
    /**
     * 批量更新失败的团
     * 计划任务每隔一段时间访问该接口
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function groupFail(){
        $time = time();
        try{
            $join = [
                ['__GROUPPRODUCT__ b','b.id=a.group_id']
            ];
            $field = 'a.*,b.product_id,b.group_succ_count,b.group_succ_time';
            $groupListFail = db('groupdetail')->alias('a')->join($join)->where(['a.status'=>1,'a.is_pay'=>1])->where('a.end_date','<=',$time)->field($field)->select();
            if($groupListFail){
                $redis = Redis::getRedisConn();
                foreach ($groupListFail as $v){
                    $data = self::refund($v);
                    if($data){
                        $redis->RPush('grouprefund_list_queue',json_encode($data));
                    }
                }
            }
        }catch (Exception $ex){
            trace($ex->getMessage(),'error');
        }

    }

    public static function doRefund(){
        $redis = Redis::getRedisConn();
        $refundData = $redis->LRange('grouprefund_list_queue',0,-1);
        try{
            if($refundData){
                foreach ($refundData as $v){
                    $v = json_decode($v,true);
                    if(!empty($v)){
                        $OrderAfterSale = OrderAfterSale::where(['order_id'=>$v['order_id'],'product_id'=>$v['product_id']])->find();
                        if($OrderAfterSale){
                            if($v['pay_method'] == 1){
                                if(self::ActiveRefund($OrderAfterSale)){
                                    $redis->LRem('grouprefund_list_queue',json_encode($v),-1);
                                }
                            }elseif ($v['pay_method'] == 3){
                                if(self::BalanceRefund($OrderAfterSale,$v)){
                                    $redis->LRem('grouprefund_list_queue',json_encode($v),-1);
                                }
                            }else{
                                //todo
                            }
                        }else{
                            $redis->LRem('grouprefund_list_queue',json_encode($v),-1);
                        }
                    }
                }
            }
        }catch (Exception $ex){
            trace($ex->getMessage(),'error');
        }

    }

    private static function refund($v){
        Db::startTrans();
        try{
            $order = \app\common\model\Order::get($v['order_id']);
            $member = \app\admin\model\Member::where('id',$order->member_id)->field('account_number')->find();
            $orderpro = Orderitem::where(['order_id'=>$v['order_id'],'product_id'=>$v['product_id']])->find();
            self::checkorder($order,$orderpro);
            $out_refund_no = \app\api\service\Order::makeOrderNo();
            $id = BaseHelper::getUUID();
            $data = [
                'id' => $id,
                'order_id' => $order->id,
                'member_phone' => $member->account_number,
                'order_item_id' => $orderpro->id,
                'out_refund_no' => $out_refund_no,
                'product_id' => $v['product_id'],
                'count' => $order->total_count,
                'refund_fee' => $order->total,
                'old_total' => $order->total,
            ];
            db('order_after_sale')->insert($data);
            $orderpro->after_sale_status = DictConstant::AfterSale_Application;
            $orderpro->save();
            Db::commit();
            $listdata['order_id'] = $order->id;
            $listdata['product_id'] = $data['product_id'];
            $listdata['pay_method'] = $order->pay_method;
            $listdata['out_refund_no'] = $out_refund_no;
            $listdata['group_succ_time'] = $v['group_succ_time'];
            $listdata['group_succ_count'] = $v['group_succ_count'];
            return $listdata;
        }catch (Exception $e){
            Db::rollback();
            trace($e->getMessage(),'error');
            return false;
        }

    }

    private static function BalanceRefund($OrderAfterSale,$data){
        Db::startTrans();
        try{
            $OrderAfterSale->status = DictConstant::AfterSale_Success;
            $OrderAfterSale->reason = 5;
            $OrderAfterSale->refund_channel = 1;
            $endDate = date('Y-m-d H:i:s',time());
            $OrderAfterSale->end_date = $endDate;
            $OrderAfterSale->save();
            $Order = \app\common\model\Order::where('id',$OrderAfterSale->order_id)->find();
            Groupdetail::where('order_id',$Order->id)->update(['status'=>3]);
            //返还用余额
            \app\admin\model\Member::where('id',$Order->member_id)->setInc('balance',$OrderAfterSale->refund_fee);
            //插入余额消费明细
            Detailed::insertDetailed($Order,2);
            Db::commit();
            return true;
            //发送模板消息
            //TemplateMessage::refundsendmessage($orderId,$group_hours,$group_nums);
        }catch (Exception $ex){
            Db::rollback();
            trace($ex->getMessage(),'error');
            return false;
        }
    }

    private static function ActiveRefund($OrderAfterSale){
        $wxRefundData = new \WxPayRefund();
        $wxRefundData->SetTotal_fee(intval($OrderAfterSale->old_total));
        $wxRefundData->SetOut_trade_no($OrderAfterSale->order_id);
        $wxRefundData->SetOut_refund_no($OrderAfterSale->out_refund_no);
        $wxRefundData->SetRefund_fee(intval($OrderAfterSale->refund_fee));
        return self::WxRefund($wxRefundData);

    }

    private static function WxRefund($wxRefundData,$OrderAfterSale){
        $wxRefund = \WxPayApi::refund($wxRefundData);
        if($wxRefund['return_code'] != 'SUCCESS' || $wxRefund['result_code'] != 'SUCCESS'){
            Log::record($wxRefund,'error');
            Log::record('微信退款失败','error');
            return false;
        }else{
            //微信退款成功后的处理逻辑
            return self::WxRefundSuccess($wxRefund,$OrderAfterSale);

        }
    }
    private static function WxRefundSuccess($wxRefund,$OrderAfterSale){
        Db::startTrans();
        try{
            $mch_id = $wxRefund['mch_id'];
            $refund_id = $wxRefund['refund_id'];
            $order_id = $wxRefund['out_trade_no'];
            $endDate = date('Y-m-d H:i:s',time());
            $OrderAfterSale->refund_id = $refund_id;
            $OrderAfterSale->op_user_id = $mch_id;
            $OrderAfterSale->end_date = $endDate;
            $OrderAfterSale->reason = 5;
            $OrderAfterSale->status = DictConstant::AfterSale_Success;
            $OrderAfterSale->save();
            Groupdetail::where('order_id',$order_id)->update(['status'=>3]);
            Db::commit();
            return true;
        }catch (Exception $ex){
            Db::rollback();
            trace($ex->getMessage(),'error');
            return false;
        }
    }

    private static function checkorder($order,$orderpro){
        if(!$order){
            throw new ParameterException([
                'msg' => '该订单不存在'
            ]);
        }
        if(!$orderpro){
            throw new ParameterException([
                'msg' => '该订单商品不存在'
            ]);
        }
        if($orderpro->old_status != 2 && $orderpro->old_status != 12){
            throw new ParameterException([
                'msg' => '此商品不能进行售后了'
            ]);
        }
    }
}